import os
from pathlib import Path
from queue import Queue
import threading
from tkinter import filedialog
from typing import Union
from .view import *

class EVAnalyzeBox(Tk):
    def __init__(self,cprocfile:str):
        super().__init__()
        self._file = cprocfile
        self.title("EV行程分析器")
        self.geometry("640x400+200+20")
        self._fr=Frame(self)
        self._fr.pack(side='bottom',anchor='center',fill='x')

        self._type_var = StringVar()
        TYPES = ["(所有)","出发","到达","充电","充完","故障","延误","警告"]
        self._optionType = OptionMenu(self._fr, self._type_var, TYPES[0], *TYPES)
        self._optionType.grid(column=0,row=0)

        self._lb1 = Label(self._fr,text="车辆")
        self._lb1.grid(column=1,row=0)

        self._entryVeh=Entry(self._fr,width=8)
        self._entryVeh.grid(column=2,row=0)

        self._lb2 = Label(self._fr,text="行程")
        self._lb2.grid(column=3,row=0)

        self._entryTrip=Entry(self._fr,width=8)
        self._entryTrip.grid(column=4,row=0)

        self._btnFilter=Button(self._fr,text="筛选",command=lambda:self._Q.put(('F',None)))
        self._btnFilter.grid(column=5,row=0)

        self._btnSave=Button(self._fr,text="保存",command=self.save)
        self._btnSave.grid(column=6,row=0)

        self.tree = Treeview(self) 
        self.tree['show'] = 'headings'
        self.tree["columns"] = ("time", "type", "veh", "soc", "trip", "info")
        self.tree.column("time", width=80, stretch=NO)
        self.tree.column("type", width=60, stretch=NO)
        self.tree.column("veh", width=80, stretch=NO)
        self.tree.column("soc", width=80, stretch=NO)
        self.tree.column("trip", width=60, stretch=NO)
        self.tree.column("info", width=200, stretch=YES)
        self.tree.heading("time", text="时间")
        self.tree.heading("type", text="类型")
        self.tree.heading("veh", text="车辆")
        self.tree.heading("soc", text="SoC")
        self.tree.heading("trip", text="行程")
        self.tree.heading("info", text="信息")
        self.tree.pack(expand=1, fill='both')
        
        self._data = []
        self._disp = []
        self._Q = Queue()
        
        threading.Thread(target=self.load,args=(self._file,)).start()
        self.after(100,self._upd)

    def _upd(self):
        cnt = 0
        while not self._Q.empty() and cnt<50:
            op,val = self._Q.get()
            cnt += 1
            if op=='L':
                self._data = val
                self._disp = self._data
                self._Q.put(('S', None))
            elif op=='S':
                for item in self.tree.get_children():self.tree.delete(item)
                for item in self._disp:self.tree.insert("", "end", values=item)
            elif op=='F':
                ftype = self._type_var.get()
                fveh = self._entryVeh.get()
                ftrip = self._entryTrip.get()
                def check(x):
                    if ftype != "(所有)" and x[1] != ftype: return False
                    if fveh != "" and x[2] != fveh: return False
                    if ftrip != "" and x[4] != ftrip: return False
                    return True
                self._disp = [x for x in self._data if check(x)]
                self._Q.put(('S', None))
        self.after(100,self._upd)
    
    @staticmethod
    def __digits(s:str)->Union[None,int,float]:
        '''从字符串中提取数字'''
        ret = ""
        has_dot = False
        for c in s:
            if c.isdigit() or c == '.':
                if c == '.':
                    if has_dot: break
                    has_dot = True
                ret += c
        if ret == "": return None
        return float(ret) if has_dot else int(ret)
    
    def save(self):
        filename = filedialog.asksaveasfilename(title="保存为",filetypes=[("csv文件",".csv")],initialdir=os.getcwd())
        if filename == "": return
        with open(filename,"w",encoding="utf-8") as fp:
            fp.write("时间,类型,车辆,SoC,行程,信息\n")
            for item in self._disp:
                fp.write(f"{item[0]},{item[1]},{item[2]},{item[3]},{item[4]},{item[5].replace(',',' ').strip()}\n")
            
    def load(self,filename:str):
        while not Path(filename).exists():
            filename = filedialog.askopenfilename(title="请选择cproc.log",filetypes=[("cproc.log",".log")],initialdir=os.getcwd())
            if filename == "": os._exit(-1)
        with open(filename,"r",encoding="utf-8") as fp:
            data = []
            for ln in fp.readlines():
                p1 = ln.find('[')
                p2 = ln.find(']',p1)
                p3 = ln.find('(',p2)
                p4 = ln.find(')',p3)
                if p1 < 0 or p2 < 0 or p3 < 0 or p4 < 0: continue
                time, type = (x.strip() for x in ln[p1+1:p2].split(','))
                veh = ln[p2+1:p3].strip()
                soc, trip = (self.__digits(x.strip()) for x in ln[p3+1:p4].split(','))
                info = ln[p4+1:].strip()
                data.append((time, type, veh, str(soc)+"%", trip, info))
            self._Q.put(('L', data))